﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows;
using System.Windows.Media;
using Microsoft.Windows.Controls;

using InfFront.InfoViews.Base;

namespace InfFront.InfoViews.WPF
{
    public static class VisualSettingsAccessorExtensions
    {
        public static AppGlobals GetAppGlobals(this IVisualSettingsAccessor acc)
        {
            return (AppGlobals) acc.Manager.AppGlobals;
        }

        public static AppGlobals GetAppGlobals(this BaseInfoViewEntity ent)
        {
            return GetAppGlobals(ent.VisualSettings);
        }
    }

    public enum MainFrameStyle
    {
        [Description("Explorer")]
        Explorer,
        [Description("Menu & Tabs")]
        MenuNTabs
    };

    public enum ListWithToolbarFrameStyle
    {
        [Description("Detailed list")]
        Grid,
        [Description("Icons")]
        Icons,
        [Description("Adjustable plot")]
        Plot
    };

}

namespace InfFront.InfoViews.WPF.Settings
{
    public class Manager : BaseSettingsManager, IVisualSettingsManager
    {
        #region Private Variables
        private AppGlobals globals = null;
        #endregion Private Variables

        #region Constrution/Initialization

        public static readonly string MAIN_FRAME_STYLE_KEY = "MainFrameStyle";
        public static readonly string COLOR_PLOT_COLOR_KEY = "ColumnPlotColor";

        static Manager()
        {
            RegisterEnumProp<MainFrameStyle>(MAIN_FRAME_STYLE_KEY, MainFrameStyle.Explorer);

            RegisterColorProp("PrimaryBackgroundColor", Colors.Lavender);
            RegisterColorProp("SecondaryBackgroundColor", Colors.Azure);
            RegisterColorProp("PrimaryGridColor", Colors.White);
            RegisterColorProp("SecondaryGridColor", Colors.Azure);
            RegisterColorProp("CommandButtonColor", Colors.Azure);

            RegisterGridLengthProp("SourceListPanelWidth", 200);
            RegisterDataGridLengthProp("DataGridColumnWidth", DataGridLength.Auto);

            // MainWindow
            RegisterProp<double>("MainWindowHeight", 400);
            RegisterProp<double>("MainWindowWidth", 700);
            RegisterEnumProp<WindowState>("MainWindowState", WindowState.Normal);

            // EntryEditWindow
            RegisterProp<double>("EntryEditWindowWidth", 400);
            RegisterProp<double>("EntryEditWindowHeight", 400);
            RegisterEnumProp<WindowState>("EntryEditWindowState", WindowState.Normal);

            // EntrySelectWindow
            RegisterProp<double>("EntrySelectWindowWidth", 400);
            RegisterProp<double>("EntrySelectWindowHeight", 400);
            RegisterEnumProp<WindowState>("EntrySelectWindowState", WindowState.Normal);

            // list styling
            RegisterGridLengthProp("PlotLegendWidth", 100);
            RegisterProp<string>(COLOR_PLOT_COLOR_KEY, string.Empty);
            RegisterEnumProp<ListWithToolbarFrameStyle>("ListWithToolbarFrameStyle", ListWithToolbarFrameStyle.Grid);
        }

        public Manager(AppGlobals globals)
            : base()
        {
            this.globals = globals;
        }

        public AppGlobals AppGlobals
        {
            get { return globals; }
        }

        #endregion Constrution/Initialization

        protected static void RegisterColorProp(string name, Color defValue)
        {
            var p = new ColorSettingPropertyDescriptor(name, defValue);
            properties.Add(p);
        }

        protected static void RegisterGridLengthProp(string name, double defValue)
        {
            var p = new GridLengthSettingPropertyDescriptor(name, new GridLength(defValue));
            properties.Add(p);
        }

        protected static void RegisterDataGridLengthProp(string name, DataGridLength defValue)
        {
            var p = new DataGridLengthSettingPropertyDescriptor(name, defValue);
            properties.Add(p);
        }

        #region IVisualSettingsManager Members

        object IVisualSettingsManager.AppGlobals
        {
            get { return AppGlobals; }
        }

        #endregion
    }

    /////////////////////////////////////////////////////////////////////////////
    //  custom PropertyMetadatas

    internal class ColorSettingPropertyDescriptor : SettingPropertyDescriptor
    {
        public ColorSettingPropertyDescriptor(string name, Color defValue)
            : base(name, typeof(Color), defValue)
        {
        }

        public override object ConvertToDb(object value)
        {
            var asColor = (Color) value;
            return asColor.ToString();
        }

        public override object ConvertFromDb(object value)
        {
            var asString = (string) value;
            return ColorConverter.ConvertFromString(asString);
        }
    }

    internal class GridLengthSettingPropertyDescriptor : SettingPropertyDescriptor
    {
        public GridLengthSettingPropertyDescriptor(string name, GridLength defValue)
            : base(name, typeof(GridLength), defValue)
        {
        }

        public override object ConvertToDb(object value)
        {
            var asGLength = (GridLength)value;
            return asGLength.Value;
        }

        public override object ConvertFromDb(object value)
        {
            var asDouble = (double) value;
            return new GridLength(asDouble);
        }
    }

    internal class DataGridLengthSettingPropertyDescriptor : SettingPropertyDescriptor
    {
        private static readonly DoubleConverter doubleConverter = new DoubleConverter();

        public DataGridLengthSettingPropertyDescriptor(string name, DataGridLength defValue)
            : base(name, typeof(DataGridLength), defValue)
        {
        }

        public override object ConvertToDb(object value)
        {
            var asGLength = (DataGridLength)value;
            switch (asGLength.UnitType)
            {
                case DataGridLengthUnitType.Auto:
                    return "Auto";
                default:
                    return asGLength.Value.ToString();
            }
        }

        public override object ConvertFromDb(object value)
        {
            var asString = (string)value;
            switch (asString)
            {
                case "Auto":
                    return DataGridLength.Auto;
                default:
                    return new DataGridLength((double)doubleConverter.ConvertFromString(asString));
            }
        }
    }
}
